package com.smasher.widget.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;

import com.smasher.widget.R;

/**
 * @author matao
 * @date 2019/5/9
 */
public class FlowLayout extends ViewGroup {

    public static final String TAG = "FlowLayout";

    private int mHorizontalSpacing = 16;
    private int mVerticalSpacing = 30;

    public FlowLayout(Context context) {
        this(context, null);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        try (TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout, defStyleAttr, defStyleRes)) {
            mHorizontalSpacing =
                    array.getDimensionPixelSize(R.styleable.FlowLayout_flow_horizontalSpacing, 16);
            mVerticalSpacing =
                    array.getDimensionPixelSize(R.styleable.FlowLayout_flow_verticalSpacing, 24);
            Log.i(TAG, "FlowLayout: mHorizontalSpacing=" + mHorizontalSpacing + " mVerticalSpacing=" + mVerticalSpacing);
        } catch (Exception e) {
            Log.e(TAG, "FlowLayout: ", e);
        }
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
        int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
        int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);
        int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);
        Log.i(TAG, "onMeasure: measureWidth=" + measureWidth + " measureHeight=" + measureHeight);

        int width = 0;
        int height = 0;
        int lineWidth = 0;
        int lineHeight = 0;

        int count = getChildCount();
        Log.i(TAG, "onMeasure: paddingStart=" + getPaddingStart());
        Log.i(TAG, "onMeasure: paddingEnd=" + getPaddingEnd());
        Log.i(TAG, "onMeasure: childCount=" + count);
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() == GONE) continue;

            measureChild(child, widthMeasureSpec, heightMeasureSpec);

            MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayoutParams();
            int childWidth = child.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin;
            int childHeight = child.getMeasuredHeight() + layoutParams.topMargin + layoutParams.bottomMargin;


            if (lineWidth + childWidth + mHorizontalSpacing > measureWidth) {
                //需要换行
                width = Math.max(childWidth, measureWidth);
                height += (lineHeight + mVerticalSpacing);
                lineHeight = childHeight;
                lineWidth = childWidth;
            } else {
                lineWidth += (childWidth + mHorizontalSpacing);
                lineHeight = Math.max(lineHeight, childHeight);
            }
        }

        // 添加最后一行的高度
        height += (lineHeight);
        width = Math.max(width, lineWidth);

        // 加上 padding
        width += getPaddingStart() + getPaddingEnd();
        height += getPaddingTop() + getPaddingBottom();

        Log.i(TAG, "onMeasure: with=" + width + " height=" + height);
        // int resultWidth = measureWidthMode == MeasureSpec.EXACTLY ? measureWidth : width;
        // int resultHeight = measureHeightMode == MeasureSpec.EXACTLY ? measureHeight : height;

        // 如果宽度模式是 AT_MOST 或 UNSPECIFIED，则使用计算出的宽度
        if (measureWidthMode != MeasureSpec.EXACTLY) {
            measureWidth = width;
        }
        // 如果高度模式是 AT_MOST 或 UNSPECIFIED，则使用计算出的高度
        if (measureHeightMode != MeasureSpec.EXACTLY) {
            measureHeight = height;
        }

        setMeasuredDimension(measureWidth, measureHeight);

    }


    @Override
    protected LayoutParams generateLayoutParams(LayoutParams p) {
        return new MarginLayoutParams(p);
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left = getPaddingLeft();
        int top = getPaddingTop();
        int lineHeight = 0;

        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            if (child.getVisibility() == GONE) continue;

            MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();

            if (left + mHorizontalSpacing + childWidth + lp.leftMargin + lp.rightMargin > getMeasuredWidth()) {
                // 换行
                left = getPaddingLeft();
                top += (lineHeight + mVerticalSpacing);
                lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
            } else {
                lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
            }

            int lc = left + lp.leftMargin;
            int tc = top + lp.topMargin;
            int rc = lc + childWidth;
            int bc = tc + childHeight;

            child.layout(lc, tc, rc, bc);
            left += childWidth + mHorizontalSpacing + lp.leftMargin + lp.rightMargin;
        }
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
    }
}
